package org.apache.commons.graph.builder

import org.apache.commons.graph.CommonsGraph.newUndirectedMutableGraph
import org.apache.commons.graph.Graph
import org.apache.commons.graph.model.BaseLabeledVertex
import org.apache.commons.graph.model.BaseLabeledWeightedEdge
import org.apache.commons.graph.model.UndirectedMutableGraph
import org.apache.commons.graph.newUndirectedMutableGraph
import org.junit.Assert
import org.junit.Test

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

class GraphBuilderTestCase {
    @Test
    fun testVerifyProducedGraphesAreEquals() {
        val expected = UndirectedMutableGraph<BaseLabeledVertex, BaseLabeledWeightedEdge<Double>>()

        // building Graph with traditional APIs...
        val start = BaseLabeledVertex("start")
        val a = BaseLabeledVertex("a")
        val b = BaseLabeledVertex("b")
        val c = BaseLabeledVertex("c")
        val d = BaseLabeledVertex("d")
        val e = BaseLabeledVertex("e")
        val goal = BaseLabeledVertex("goal")

        expected.addVertex(start)
        expected.addVertex(a)
        expected.addVertex(b)
        expected.addVertex(c)
        expected.addVertex(d)
        expected.addVertex(e)
        expected.addVertex(goal)

        expected.addEdge(start, BaseLabeledWeightedEdge("start <-> a", 1.5), a)
        expected.addEdge(start, BaseLabeledWeightedEdge("start <-> d", 2.0), d)

        expected.addEdge(a, BaseLabeledWeightedEdge("a <-> b", 2.0), b)
        expected.addEdge(b, BaseLabeledWeightedEdge("b <-> c", 3.0), c)
        expected.addEdge(c, BaseLabeledWeightedEdge("c <-> goal", 3.0), goal)

        expected.addEdge(d, BaseLabeledWeightedEdge("d <-> e", 3.0), e)
        expected.addEdge(e, BaseLabeledWeightedEdge("e <-> goal", 2.0), goal)

        // ... and using the EDSL :)
        val actual: UndirectedMutableGraph<BaseLabeledVertex, BaseLabeledWeightedEdge<Double>> =
            newUndirectedMutableGraph(object :AbstractGraphConnection<BaseLabeledVertex, BaseLabeledWeightedEdge<Double>>() {
                override fun connect() {
                    val start = addVertex(BaseLabeledVertex("start"))
                    val a = addVertex(BaseLabeledVertex("a"))
                    val b = addVertex(BaseLabeledVertex("b"))
                    val c = addVertex(BaseLabeledVertex("c"))
                    val d = addVertex(BaseLabeledVertex("d"))
                    val e = addVertex(BaseLabeledVertex("e"))
                    val goal = addVertex(BaseLabeledVertex("goal"))

                    addEdge(BaseLabeledWeightedEdge("start <-> a", 1.5)) from start to a
                    addEdge(BaseLabeledWeightedEdge("start <-> d", 2.0)).from(start).to(d)

                    addEdge(BaseLabeledWeightedEdge("a <-> b", 2.0)).from(a).to(b)
                    addEdge(BaseLabeledWeightedEdge("b <-> c", 3.0)).from(b).to(c)
                    addEdge(BaseLabeledWeightedEdge("c <-> goal", 3.0)).from(c).to(goal)

                    addEdge(BaseLabeledWeightedEdge("d <-> e", 3.0)).from(d).to(e)
                    addEdge(BaseLabeledWeightedEdge("e <-> goal", 2.0)).from(e).to(goal)
                }
            })

        Assert.assertEquals(expected, actual)
    }
}


val actual1 = Graph.newUndirectedMutableGraph{
    val start = "start"
    val a = "a"

    val start_a = BaseLabeledWeightedEdge("start <-> a", 1.5)

    start to a edge BaseLabeledWeightedEdge("start <-> a", 1.5)
    start_a edgeOn (start to a)
    start_a from start to a
    start on start_a to a

    }

fun test(){

    actual1.apply {
        val start1 = "start1".add()
        val a = "a".addOrGet()

        start1 to a edge BaseLabeledWeightedEdge("start <-> a", 1.5)
    }
}